package cn.lzm;

import cn.lzm.config.RegistryConfig;
import cn.lzm.config.RpcConfig;
import cn.lzm.registry.Registry;
import cn.lzm.registry.RegistryFactory;
import cn.lzm.utils.ConfigUtils;
import com.alibaba.fastjson2.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author lzm
 * @Date 2024/7/21
 * @description
 */
public class RpcApplication {

    private static final Logger log = LoggerFactory.getLogger(RpcApplication.class);
    public static volatile RpcConfig rpcConfig;

    /**
     * 框架初始化，
     * 加载配置文件
     */
    public static void init() {
        RpcConfig config;
        try {
            config = ConfigUtils.getRpcConfig("");
        } catch (Exception e) {
            // 配置文件加载失败，使用默认配置
            config = new RpcConfig();
        }
        rpcConfig = config;

        // 注册中心初始化
        RegistryConfig registryConfig = rpcConfig.getRegistryConfig();
        Registry registry = RegistryFactory.getInstance(registryConfig.getType());
        registry.init(registryConfig);
        log.info("注册中心初始化完成，config={}", JSON.toJSON(registryConfig));

        // 实现服务关闭时，自动下线。当JVM退出时会自动下线
        Runtime.getRuntime().addShutdownHook(new Thread(registry::destroy));
    }

    /**
     * 获取rpc配置
     * @return rpc配置
     * 为什么要2个if, 外层的if判断是为了提升性能，不用每次经过这个方法都需要申请锁
     * 内层的if判断是否可以去掉呢？ 答案是不可以，一旦去掉后，就不是单例模式了，因为可能最初会有3个线程或者更多的
     * 线程通过了第一层if判断，然后后面这3个线程最终都会获取到锁，只是各自获取到锁的时机不同而已，
     * 最后就是每个线程都都创建了一个rpcConfig对象，违背了单例模式的原则
     */
    public static RpcConfig getRpcConfig() {
        if (rpcConfig == null) {
            synchronized (RpcApplication.class) {
                if (rpcConfig == null) { // 这个if判断是否可以去掉？
                    init();
                }
            }
        }
        return rpcConfig;
    }



}
